package org.dreamwork.jasmine2.compiler.gui;

import org.dreamwork.jasmine2.compiler.JasmineCompiler;
import org.dreamwork.jasmine2.compiler.JasmineCompilerFacade;
import org.dreamwork.jasmine2.util.StringConverter;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: seth.yang
 * Date: 2010-4-12
 * Time: 21:24:40
 */
public class JasmineCompilerFrame extends JFrame {
    private JTextField txtSource;
    private JButton btnBrowseSource;
    private JTextField txtOutput;
    private JButton btnBrowseOutput;
    private JTextField txtArchive;
    private JButton btnOK;
    private JButton btnCancel;
    private JLabel lblMessage;
    private JPanel root;
    private JFileChooser chooser = new JFileChooser ();

    private JasmineCompiler compiler;

    static {
        try {
            UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }

    public JasmineCompilerFrame (final JasmineCompiler compiler) throws IOException {
        setContentPane (root);
        getRootPane ().setDefaultButton (btnOK);
        getRootPane ().registerKeyboardAction (new ActionListener() {
            public void actionPerformed (ActionEvent e) {
                dispose ();
            }
        }, KeyStroke.getKeyStroke (KeyEvent.VK_ESCAPE, 0), 0);
        this.compiler = compiler;
        ActionListener browseSourceAction = new ActionListener() {
            public void actionPerformed (ActionEvent e) {
                File file = browse ();
                if (file != null) txtSource.setText (file.getAbsolutePath ());
            }
        };
        btnBrowseSource.addActionListener (browseSourceAction);
        ActionListener browseOutputAction = new ActionListener() {
            public void actionPerformed (ActionEvent e) {
                File file = browse ();
                if (file != null) txtOutput.setText (file.getAbsolutePath ());
            }
        };
        btnBrowseOutput.addActionListener (browseOutputAction);
        ActionListener okAction = new ActionListener() {
            public void actionPerformed (ActionEvent e) {
                ok ();
            }
        };
        btnOK.addActionListener (okAction);
        ActionListener cancelAction = new ActionListener() {
            public void actionPerformed (ActionEvent e) {
                dispose ();
            }
        };
        btnCancel.addActionListener (cancelAction);
        Runnable runner = new Runnable() {
            public void run () {
                SwingUtilities.invokeLater (messageChanger);               
            }
        };
        compiler.setRunner (runner);
        chooser.setFileFilter (new FileFilter() {
            @Override
            public boolean accept (File f) {
                return f.isDirectory ();
            }

            @Override
            public String getDescription () {
                return null;
            }
        });
        chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);

        Dimension min = btnBrowseSource.getPreferredSize ();
        min.width = min.height;
        btnBrowseSource.setPreferredSize (min);
        btnBrowseOutput.setPreferredSize (min);

        min = txtSource.getPreferredSize ();
        min.width = 450;
        txtSource.setPreferredSize (min);

        setTitle ("Jasmine Compiler GUI");

        pack ();

        Dimension d = getSize ();
        Dimension D = Toolkit.getDefaultToolkit ().getScreenSize ();
        int x = (D.width - d.width) / 2;
        int y = (D.height - d.height) / 2;
        setLocation (x, y);
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        setResizable (false);

        this.setIconImage (ImageIO.read (getClass ().getResourceAsStream ("jasmine.png")));
    }

    private void ok () {
        compiler.setBaseDir (txtSource.getText ());
        compiler.setDistDir (txtOutput.getText () + "/classes");
        compiler.setSrcDir (txtOutput.getText () + "/src");
        new Thread() {
            @Override
            public void run () {
                try {
                    compiler.compile ();
                } catch (Exception ex) {
                    throw new RuntimeException (ex);
                }
            }
        }.start ();
        setButtonStatus (false);
    }

    private File browse () {
        chooser.showOpenDialog (this);
        return chooser.getSelectedFile ();
    }

    private void setMessage (final String text) {
        SwingUtilities.invokeLater (new Runnable() {
            public void run () {
                lblMessage.setText (text);
            }
        });
    }

    private Runnable messageChanger = new Runnable() {
        public void run () {
            lblMessage.setText ("正在编译 " + compiler.getCurrentFileName ());
            if (compiler.isWalkDone ()) {
                if (compiler.getCursor () == compiler.getTotalFiles ()) {
                    String archive = txtArchive.getText ().trim ();
                    if (!StringConverter.isEmpty (archive)) {
                        try {
                            setMessage ("正在创建包文件: " + archive);
                            JasmineCompilerFacade.createArchive (archive, compiler.getDistDir ());
                            setMessage ("正在删除临时文件...");
                            cleanUp ();
                            setMessage ("完成");
                        } catch (Exception e) {
                            e.printStackTrace ();
                        }
                    }
                    setButtonStatus (true);
                }
            }
        }
    };

    private void cleanUp () {
        File dir = new File (txtOutput.getText (), "classes");
        dir.deleteOnExit ();
        dir = new File (txtOutput.getText (), "src");
        dir.deleteOnExit ();
    }

    private void setButtonStatus (boolean status) {
        btnBrowseSource.setEnabled (status);
        btnBrowseOutput.setEnabled (status);
        btnOK.setEnabled (status);
        btnCancel.setEnabled (status);
    }
}